﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.IO;
using Microsoft.WindowsAzure;
using Microsoft.WindowsAzure.StorageClient;
using System.Diagnostics;

namespace BlobDownloader
{
    class Program
    {
        static void Main(string[] args)
        {
            var name = string.Empty;
            var key = string.Empty;
            var containerName = string.Empty;
            var blobName = string.Empty;
            var fullpath = string.Empty;

            // retrieve the parameters
            var arguments = ArgumentsParser.ToArguments(args);
            if (!arguments.TryGetValueByKeys(out name, "-n") ||
                !arguments.TryGetValueByKeys(out key, "-k") ||
                !arguments.TryGetValueByKeys(out containerName, "-c") ||
                !arguments.TryGetValueByKeys(out blobName, "-b") ||
                !arguments.TryGetValueByKeys(out fullpath, "-f"))
            {
                Help();
                return;
            }
            
            // delete the target file if exist
            if (File.Exists(fullpath))
            {
                File.Delete(fullpath);
            }

            // download the blob to file
            var blobPath = string.Empty;
            var sw = new Stopwatch();
            sw.Start();
            try
            {
                var account = new CloudStorageAccount(new StorageCredentialsAccountAndKey(name, key), false);

                var client = account.CreateCloudBlobClient();
                client.Timeout = new TimeSpan(1, 0, 0);
                client.WriteBlockSizeInBytes = 4 * 1024 * 1024;
                client.RetryPolicy = RetryPolicies.Retry(20, TimeSpan.Zero);
                
                var container = client.GetContainerReference(containerName);
                var blob = container.GetBlobReference(blobName);
                blobPath = blob.Uri.AbsoluteUri;

                var options = new BlobRequestOptions()
                {
                    Timeout = new TimeSpan(1, 0, 0),
                    RetryPolicy = RetryPolicies.Retry(20, TimeSpan.Zero)
                };

                using (var stream = File.OpenWrite(fullpath))
                {
                    blob.DownloadToStream(stream);
                }

                sw.Stop();
                Console.WriteLine("DONE: Downloaded the blob ({0}) to {1} in {2} seconds.", blobPath, fullpath, sw.ElapsedMilliseconds / (double)1000);
            }
            catch (Exception ex)
            {
                Console.WriteLine("ERROR: Failed to download the blob from {0}. \n{1}", blobPath, ex.ToString());
            }
        }

        static void Help()
        {
            Console.WriteLine("BLOB Downloader Usage: ");
            Console.WriteLine("blobdownloader -n <Storage Account Name> -k <Storage Account Key> -c <Container Name> -b <Blob Name> -f <Downloaded Full Path>");
        }
    }
}
